1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module gtk.ListStore; 26 27 private import glib.ConstructionException; 28 private import glib.MemorySlice; 29 private import gobject.ObjectG; 30 private import gobject.Value; 31 private import gtk.BuildableIF; 32 private import gtk.BuildableT; 33 private import gtk.TreeDragDestIF; 34 private import gtk.TreeDragDestT; 35 private import gtk.TreeDragSourceIF; 36 private import gtk.TreeDragSourceT; 37 private import gtk.TreeIter; 38 private import gtk.TreeModelIF; 39 private import gtk.TreeModelT; 40 private import gtk.TreeSortableIF; 41 private import gtk.TreeSortableT; 42 private import gtk.c.functions; 43 public import gtk.c.types; 44 45 46 /** 47 * A list-like data structure that can be used with the [class@Gtk.TreeView]. 48 * 49 * The `GtkListStore` object is a list model for use with a `GtkTreeView` 50 * widget. It implements the `GtkTreeModel` interface, and consequentialy, 51 * can use all of the methods available there. It also implements the 52 * `GtkTreeSortable` interface so it can be sorted by the view. 53 * Finally, it also implements the tree 54 * [drag](iface.TreeDragSource.html) and [drop](iface.TreeDragDest.html) 55 * interfaces. 56 * 57 * The `GtkListStore` can accept most `GType`s as a column type, though 58 * it can’t accept all custom types. Internally, it will keep a copy of 59 * data passed in (such as a string or a boxed pointer). Columns that 60 * accept `GObject`s are handled a little differently. The 61 * `GtkListStore` will keep a reference to the object instead of copying the 62 * value. As a result, if the object is modified, it is up to the 63 * application writer to call [method@Gtk.TreeModel.row_changed] to emit the 64 * [signal@Gtk.TreeModel::row_changed] signal. This most commonly affects lists 65 * with [class@Gdk.Texture]s stored. 66 * 67 * An example for creating a simple list store: 68 * 69 * ```c 70 * enum { 71 * COLUMN_STRING, 72 * COLUMN_INT, 73 * COLUMN_BOOLEAN, 74 * N_COLUMNS 75 * }; 76 * 77 * { 78 * GtkListStore *list_store; 79 * GtkTreePath *path; 80 * GtkTreeIter iter; 81 * int i; 82 * 83 * list_store = gtk_list_store_new (N_COLUMNS, 84 * G_TYPE_STRING, 85 * G_TYPE_INT, 86 * G_TYPE_BOOLEAN); 87 * 88 * for (i = 0; i < 10; i++) 89 * { 90 * char *some_data; 91 * 92 * some_data = get_some_data (i); 93 * 94 * // Add a new row to the model 95 * gtk_list_store_append (list_store, &iter); 96 * gtk_list_store_set (list_store, &iter, 97 * COLUMN_STRING, some_data, 98 * COLUMN_INT, i, 99 * COLUMN_BOOLEAN, FALSE, 100 * -1); 101 * 102 * // As the store will keep a copy of the string internally, 103 * // we free some_data. 104 * g_free (some_data); 105 * } 106 * 107 * // Modify a particular row 108 * path = gtk_tree_path_new_from_string ("4"); 109 * gtk_tree_model_get_iter (GTK_TREE_MODEL (list_store), 110 * &iter, 111 * path); 112 * gtk_tree_path_free (path); 113 * gtk_list_store_set (list_store, &iter, 114 * COLUMN_BOOLEAN, TRUE, 115 * -1); 116 * } 117 * ``` 118 * 119 * # Performance Considerations 120 * 121 * Internally, the `GtkListStore` was originally implemented with a linked list 122 * with a tail pointer. As a result, it was fast at data insertion and deletion, 123 * and not fast at random data access. The `GtkListStore` sets the 124 * `GTK_TREE_MODEL_ITERS_PERSIST` flag, which means that `GtkTreeIter`s can be 125 * cached while the row exists. Thus, if access to a particular row is needed 126 * often and your code is expected to run on older versions of GTK, it is worth 127 * keeping the iter around. 128 * 129 * # Atomic Operations 130 * 131 * It is important to note that only the methods 132 * gtk_list_store_insert_with_values() and gtk_list_store_insert_with_valuesv() 133 * are atomic, in the sense that the row is being appended to the store and the 134 * values filled in in a single operation with regard to `GtkTreeModel` signaling. 135 * In contrast, using e.g. gtk_list_store_append() and then gtk_list_store_set() 136 * will first create a row, which triggers the `GtkTreeModel::row-inserted` signal 137 * on `GtkListStore`. The row, however, is still empty, and any signal handler 138 * connecting to `GtkTreeModel::row-inserted` on this particular store should be prepared 139 * for the situation that the row might be empty. This is especially important 140 * if you are wrapping the `GtkListStore` inside a `GtkTreeModel`Filter and are 141 * using a `GtkTreeModel`FilterVisibleFunc. Using any of the non-atomic operations 142 * to append rows to the `GtkListStore` will cause the 143 * `GtkTreeModel`FilterVisibleFunc to be visited with an empty row first; the 144 * function must be prepared for that. 145 * 146 * # GtkListStore as GtkBuildable 147 * 148 * The GtkListStore implementation of the [iface@Gtk.Buildable] interface allows 149 * to specify the model columns with a `<columns>` element that may contain 150 * multiple `<column>` elements, each specifying one model column. The “type” 151 * attribute specifies the data type for the column. 152 * 153 * Additionally, it is possible to specify content for the list store 154 * in the UI definition, with the `<data>` element. It can contain multiple 155 * `<row>` elements, each specifying to content for one row of the list model. 156 * Inside a `<row>`, the `<col>` elements specify the content for individual cells. 157 * 158 * Note that it is probably more common to define your models in the code, 159 * and one might consider it a layering violation to specify the content of 160 * a list store in a UI definition, data, not presentation, and common wisdom 161 * is to separate the two, as far as possible. 162 * 163 * An example of a UI Definition fragment for a list store: 164 * 165 * ```xml 166 * <object class="GtkListStore"> 167 * <columns> 168 * <column type="gchararray"/> 169 * <column type="gchararray"/> 170 * <column type="gint"/> 171 * </columns> 172 * <data> 173 * <row> 174 * <col id="0">John</col> 175 * <col id="1">Doe</col> 176 * <col id="2">25</col> 177 * </row> 178 * <row> 179 * <col id="0">Johan</col> 180 * <col id="1">Dahlin</col> 181 * <col id="2">50</col> 182 * </row> 183 * </data> 184 * </object> 185 * ``` 186 */ 187 public class ListStore : ObjectG, BuildableIF, TreeDragDestIF, TreeDragSourceIF, TreeModelIF, TreeSortableIF 188 { 189 /** the main Gtk struct */ 190 protected GtkListStore* gtkListStore; 191 192 /** Get the main Gtk struct */ 193 public GtkListStore* getListStoreStruct(bool transferOwnership = false) 194 { 195 if (transferOwnership) 196 ownedRef = false; 197 return gtkListStore; 198 } 199 200 /** the main Gtk struct as a void* */ 201 protected override void* getStruct() 202 { 203 return cast(void*)gtkListStore; 204 } 205 206 /** 207 * Sets our main struct and passes it to the parent class. 208 */ 209 public this (GtkListStore* gtkListStore, bool ownedRef = false) 210 { 211 this.gtkListStore = gtkListStore; 212 super(cast(GObject*)gtkListStore, ownedRef); 213 } 214 215 // add the Buildable capabilities 216 mixin BuildableT!(GtkListStore); 217 218 // add the TreeDragDest capabilities 219 mixin TreeDragDestT!(GtkListStore); 220 221 // add the TreeDragSource capabilities 222 mixin TreeDragSourceT!(GtkListStore); 223 224 // add the TreeModel capabilities 225 mixin TreeModelT!(GtkListStore); 226 227 // add the TreeSortable capabilities 228 mixin TreeSortableT!(GtkListStore); 229 230 /** 231 * Creates a top level iteractor. 232 * I don't think lists have but the top level iteractor 233 */ 234 TreeIter createIter() 235 { 236 GtkTreeIter* iter = new GtkTreeIter; 237 gtk_list_store_append(getListStoreStruct(), iter); 238 return new TreeIter(iter); 239 } 240 241 /** */ 242 void setValue(TYPE)(TreeIter iter, int column, TYPE value) 243 { 244 Value v = new Value(value); 245 gtk_list_store_set_value(gtkListStore, iter.getTreeIterStruct(), column, v.getValueStruct()); 246 } 247 248 /** 249 */ 250 251 /** */ 252 public static GType getType() 253 { 254 return gtk_list_store_get_type(); 255 } 256 257 /** 258 * Non-vararg creation function. Used primarily by language bindings. 259 * 260 * Params: 261 * types = an array of `GType` types for the columns, from first to last 262 * 263 * Returns: a new `GtkListStore` 264 * 265 * Throws: ConstructionException GTK+ fails to create the object. 266 */ 267 public this(GType[] types) 268 { 269 auto __p = gtk_list_store_newv(cast(int)types.length, types.ptr); 270 271 if(__p is null) 272 { 273 throw new ConstructionException("null returned by newv"); 274 } 275 276 this(cast(GtkListStore*) __p, true); 277 } 278 279 /** 280 * Appends a new row to @list_store. @iter will be changed to point to this new 281 * row. The row will be empty after this function is called. To fill in 282 * values, you need to call gtk_list_store_set() or gtk_list_store_set_value(). 283 * 284 * Params: 285 * iter = An unset `GtkTreeIter` to set to the appended row 286 */ 287 public void append(out TreeIter iter) 288 { 289 GtkTreeIter* outiter = sliceNew!GtkTreeIter(); 290 291 gtk_list_store_append(gtkListStore, outiter); 292 293 iter = ObjectG.getDObject!(TreeIter)(outiter, true); 294 } 295 296 /** 297 * Removes all rows from the list store. 298 */ 299 public void clear() 300 { 301 gtk_list_store_clear(gtkListStore); 302 } 303 304 /** 305 * Creates a new row at @position. @iter will be changed to point to this new 306 * row. If @position is -1 or is larger than the number of rows on the list, 307 * then the new row will be appended to the list. The row will be empty after 308 * this function is called. To fill in values, you need to call 309 * gtk_list_store_set() or gtk_list_store_set_value(). 310 * 311 * Params: 312 * iter = An unset `GtkTreeIter` to set to the new row 313 * position = position to insert the new row, or -1 for last 314 */ 315 public void insert(out TreeIter iter, int position) 316 { 317 GtkTreeIter* outiter = sliceNew!GtkTreeIter(); 318 319 gtk_list_store_insert(gtkListStore, outiter, position); 320 321 iter = ObjectG.getDObject!(TreeIter)(outiter, true); 322 } 323 324 /** 325 * Inserts a new row after @sibling. If @sibling is %NULL, then the row will be 326 * prepended to the beginning of the list. @iter will be changed to point to 327 * this new row. The row will be empty after this function is called. To fill 328 * in values, you need to call gtk_list_store_set() or gtk_list_store_set_value(). 329 * 330 * Params: 331 * iter = An unset `GtkTreeIter` to set to the new row 332 * sibling = A valid `GtkTreeIter` 333 */ 334 public void insertAfter(out TreeIter iter, TreeIter sibling) 335 { 336 GtkTreeIter* outiter = sliceNew!GtkTreeIter(); 337 338 gtk_list_store_insert_after(gtkListStore, outiter, (sibling is null) ? null : sibling.getTreeIterStruct()); 339 340 iter = ObjectG.getDObject!(TreeIter)(outiter, true); 341 } 342 343 /** 344 * Inserts a new row before @sibling. If @sibling is %NULL, then the row will 345 * be appended to the end of the list. @iter will be changed to point to this 346 * new row. The row will be empty after this function is called. To fill in 347 * values, you need to call gtk_list_store_set() or gtk_list_store_set_value(). 348 * 349 * Params: 350 * iter = An unset `GtkTreeIter` to set to the new row 351 * sibling = A valid `GtkTreeIter` 352 */ 353 public void insertBefore(out TreeIter iter, TreeIter sibling) 354 { 355 GtkTreeIter* outiter = sliceNew!GtkTreeIter(); 356 357 gtk_list_store_insert_before(gtkListStore, outiter, (sibling is null) ? null : sibling.getTreeIterStruct()); 358 359 iter = ObjectG.getDObject!(TreeIter)(outiter, true); 360 } 361 362 /** 363 * A variant of gtk_list_store_insert_with_values() which 364 * takes the columns and values as two arrays, instead of 365 * varargs. 366 * 367 * This function is mainly intended for language-bindings. 368 * 369 * Params: 370 * iter = An unset `GtkTreeIter` to set to the new row 371 * position = position to insert the new row, or -1 for last 372 * columns = an array of column numbers 373 * values = an array of GValues 374 */ 375 public void insertWithValuesv(out TreeIter iter, int position, int[] columns, Value[] values) 376 { 377 GtkTreeIter* outiter = sliceNew!GtkTreeIter(); 378 379 GValue[] valuesArray = new GValue[values.length]; 380 for ( int i = 0; i < values.length; i++ ) 381 { 382 valuesArray[i] = *(values[i].getValueStruct()); 383 } 384 385 gtk_list_store_insert_with_valuesv(gtkListStore, outiter, position, columns.ptr, valuesArray.ptr, cast(int)values.length); 386 387 iter = ObjectG.getDObject!(TreeIter)(outiter, true); 388 } 389 390 /** 391 * Checks if the given iter is a valid iter for this `GtkListStore`. 392 * 393 * This function is slow. Only use it for debugging and/or testing 394 * purposes. 395 * 396 * Params: 397 * iter = the iterator to check 398 * 399 * Returns: %TRUE if the iter is valid, %FALSE if the iter is invalid. 400 */ 401 public bool iterIsValid(TreeIter iter) 402 { 403 return gtk_list_store_iter_is_valid(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct()) != 0; 404 } 405 406 /** 407 * Moves @iter in @store to the position after @position. Note that this 408 * function only works with unsorted stores. If @position is %NULL, @iter 409 * will be moved to the start of the list. 410 * 411 * Params: 412 * iter = A `GtkTreeIter` 413 * position = A `GtkTreeIter` 414 */ 415 public void moveAfter(TreeIter iter, TreeIter position) 416 { 417 gtk_list_store_move_after(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), (position is null) ? null : position.getTreeIterStruct()); 418 } 419 420 /** 421 * Moves @iter in @store to the position before @position. Note that this 422 * function only works with unsorted stores. If @position is %NULL, @iter 423 * will be moved to the end of the list. 424 * 425 * Params: 426 * iter = A `GtkTreeIter` 427 * position = A `GtkTreeIter` 428 */ 429 public void moveBefore(TreeIter iter, TreeIter position) 430 { 431 gtk_list_store_move_before(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), (position is null) ? null : position.getTreeIterStruct()); 432 } 433 434 /** 435 * Prepends a new row to @list_store. @iter will be changed to point to this new 436 * row. The row will be empty after this function is called. To fill in 437 * values, you need to call gtk_list_store_set() or gtk_list_store_set_value(). 438 * 439 * Params: 440 * iter = An unset `GtkTreeIter` to set to the prepend row 441 */ 442 public void prepend(out TreeIter iter) 443 { 444 GtkTreeIter* outiter = sliceNew!GtkTreeIter(); 445 446 gtk_list_store_prepend(gtkListStore, outiter); 447 448 iter = ObjectG.getDObject!(TreeIter)(outiter, true); 449 } 450 451 /** 452 * Removes the given row from the list store. After being removed, 453 * @iter is set to be the next valid row, or invalidated if it pointed 454 * to the last row in @list_store. 455 * 456 * Params: 457 * iter = A valid `GtkTreeIter` 458 * 459 * Returns: %TRUE if @iter is valid, %FALSE if not. 460 */ 461 public bool remove(TreeIter iter) 462 { 463 return gtk_list_store_remove(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct()) != 0; 464 } 465 466 /** 467 * Reorders @store to follow the order indicated by @new_order. Note that 468 * this function only works with unsorted stores. 469 * 470 * Params: 471 * newOrder = an array of integers mapping the new 472 * position of each child to its old position before the re-ordering, 473 * i.e. @new_order`[newpos] = oldpos`. It must have 474 * exactly as many items as the list store’s length. 475 */ 476 public void reorder(int[] newOrder) 477 { 478 gtk_list_store_reorder(gtkListStore, newOrder.ptr); 479 } 480 481 /** 482 * This function is meant primarily for `GObject`s that inherit from `GtkListStore`, 483 * and should only be used when constructing a new `GtkListStore`. It will not 484 * function after a row has been added, or a method on the `GtkTreeModel` 485 * interface is called. 486 * 487 * Params: 488 * types = An array length n of `GType`s 489 */ 490 public void setColumnTypes(GType[] types) 491 { 492 gtk_list_store_set_column_types(gtkListStore, cast(int)types.length, types.ptr); 493 } 494 495 /** 496 * See gtk_list_store_set(); this version takes a va_list for use by language 497 * bindings. 498 * 499 * Params: 500 * iter = A valid `GtkTreeIter` for the row being modified 501 * varArgs = va_list of column/value pairs 502 */ 503 public void setValist(TreeIter iter, void* varArgs) 504 { 505 gtk_list_store_set_valist(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), varArgs); 506 } 507 508 /** 509 * Sets the data in the cell specified by @iter and @column. 510 * The type of @value must be convertible to the type of the 511 * column. 512 * 513 * Params: 514 * iter = A valid `GtkTreeIter` for the row being modified 515 * column = column number to modify 516 * value = new value for the cell 517 */ 518 public void setValue(TreeIter iter, int column, Value value) 519 { 520 gtk_list_store_set_value(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), column, (value is null) ? null : value.getValueStruct()); 521 } 522 523 /** 524 * A variant of gtk_list_store_set_valist() which 525 * takes the columns and values as two arrays, instead of 526 * varargs. This function is mainly intended for 527 * language-bindings and in case the number of columns to 528 * change is not known until run-time. 529 * 530 * Params: 531 * iter = A valid `GtkTreeIter` for the row being modified 532 * columns = an array of column numbers 533 * values = an array of GValues 534 */ 535 public void setValuesv(TreeIter iter, int[] columns, Value[] values) 536 { 537 GValue[] valuesArray = new GValue[values.length]; 538 for ( int i = 0; i < values.length; i++ ) 539 { 540 valuesArray[i] = *(values[i].getValueStruct()); 541 } 542 543 gtk_list_store_set_valuesv(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), columns.ptr, valuesArray.ptr, cast(int)values.length); 544 } 545 546 /** 547 * Swaps @a and @b in @store. Note that this function only works with 548 * unsorted stores. 549 * 550 * Params: 551 * a = A `GtkTreeIter` 552 * b = Another `GtkTreeIter` 553 */ 554 public void swap(TreeIter a, TreeIter b) 555 { 556 gtk_list_store_swap(gtkListStore, (a is null) ? null : a.getTreeIterStruct(), (b is null) ? null : b.getTreeIterStruct()); 557 } 558 }